/**
 * 
 */
package com.goktech.commons.excel.utils.abs;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.RegionUtil;

import com.goktech.commons.excel.RowFactory;
import com.goktech.commons.excel.utils.WorkBookMediatorInterface;

/**
 * @author zhongmh
 * @email yunmaozj@163.com
 * @createTime 2018年1月4日下午7:25:28
 * @desc 工作薄的操作类 中介者模式
 */
public class WorkBookMediator implements WorkBookMediatorInterface<WorkBookMediator> {

	private List<Row> rowList;
	private List<Cell> cellList;
	private List<CellRangeAddress> craList;
	private AbstractExcelWriter<?> abstractExcelWriter;
	private int cellIndex = 0;
	private int operation = -1;

	public WorkBookMediator(AbstractExcelWriter<?> abstractExcelWriter) {
		super();
		this.abstractExcelWriter = abstractExcelWriter;
		this.rowList = new ArrayList<>();
		this.cellList = new ArrayList<>();
		this.craList = new ArrayList<>();
	}

	@Override
	public WorkBookMediator row() {
		int rowIndex = abstractExcelWriter.getRowIndex();
		return row(rowIndex);
	}

	@Override
	public WorkBookMediator row(int indexRow) {
		Row row = this.abstractExcelWriter.createRow(indexRow);
		this.rowList.add(row);
		operation = 1;
		this.cellIndex = 0;
		return this;
	}

	@Override
	public WorkBookMediator cell() {
		if (this.rowList == null || this.rowList.size() == 0) {
			throw new NullPointerException("if you create cell must have row");
		}
		Row row = this.rowList.get(this.rowList.size() - 1);
		int index = row.getLastCellNum();
		return cell(index);
	}

	@Override
	public WorkBookMediator tyle(CellStyle cellStyle) {
		return null;
	}

	@Override
	public WorkBookMediator cellRangeAddress(int width, int height) {
		Row row = this.getRow();
		int rowNum = row.getRowNum();
		Cell cell = this.getCell();
		int cellNum = cell.getColumnIndex();
		CellRangeAddress cra = new CellRangeAddress(rowNum, rowNum + height, cellNum, cellNum + width - 1);
		this.craList.add(cra);
		this.operation = 0;
		this.abstractExcelWriter.sheet.addMergedRegion(cra);
		this.bottomBorderColor(IndexedColors.AQUA.index);
		// 更新行索引的位置和单元格索引的位置
		this.abstractExcelWriter.rowIndex = rowNum + height + 1;
		this.cellIndex = cellNum + width;
		return this;
	}

	@Override
	public WorkBookMediator cellRangeAddressStype() {
		return null;
	}

	@Override
	public WorkBookMediator cell(int index) {
		if (this.rowList == null || this.rowList.size() == 0) {
			throw new NullPointerException("if you create cell must have row");
		}
		Cell cell = this.rowList.get(this.rowList.size() - 1)
				.createCell(index <= 0 ? 0 : this.cellIndex > index ? this.cellIndex++ : index);
		this.cellList.add(cell);
		cell.setCellStyle(this.abstractExcelWriter.excelStyle.getStyle(""));
		operation = 0;
		return this;
	}

	@Override
	public WorkBookMediator cellRangeAddress(int firstRow, int lastRow, int firstCell, int lastCell) {
		CellRangeAddress cra = new CellRangeAddress(firstRow, lastRow, firstCell, lastCell);
		this.craList.add(cra);
		this.abstractExcelWriter.sheet.addMergedRegion(cra);
		return this;
	}

	private Row getRow() {
		if (this.rowList == null || this.rowList.size() == 0) {
			throw new NullPointerException();
		}
		return this.rowList.get(this.rowList.size() - 1);
	}

	private Cell getCell() {
		if (this.cellList == null || this.cellList.size() == 0) {
			throw new NullPointerException();
		}
		return this.cellList.get(this.cellList.size() - 1);
	}
	
	private CellRangeAddress getCra(){
		if (this.craList == null || this.craList.size() == 0) {
			throw new NullPointerException();
		}
		return this.craList.get(this.craList.size() - 1);
	}

	@Override
	public WorkBookMediator value(String vlaue) {
		this.getCell().setCellValue(vlaue);
		return this;
	}

	@Override
	public WorkBookMediator value(Date value) {
		this.getCell().setCellValue(value);
		return this;
	}

	@Override
	public WorkBookMediator value(Double value) {
		this.getCell().setCellValue(value);
		return this;
	}

	@Override
	public WorkBookMediator value(byte value) {
		this.getCell().setCellValue(value);
		return this;
	}

	@Override
	public WorkBookMediator value(boolean value) {
		this.getCell().setCellValue(value);
		return this;
	}

	@Override
	public WorkBookMediator updateIndex(int rowIndex) {
		this.abstractExcelWriter.rowIndex = rowIndex;
		return this;
	}

	@Override
	public StyleMediator<WorkBookMediator> style() {
		if (operation == -1) {
			throw new NullPointerException();
		}
		StyleMediator<WorkBookMediator> mediator = null;
		if (operation == 1)
			mediator = new StyleMediator<WorkBookMediator>(this, this.abstractExcelWriter.workbook(), this.getRow(),this.abstractExcelWriter.excelStyle);
		else
			mediator = new StyleMediator<WorkBookMediator>(this, this.abstractExcelWriter.workbook(), this.getCell(),this.abstractExcelWriter.excelStyle);
		mediator.style();
		return mediator;
	}

	@Override
	public StyleMediator<WorkBookMediator> style(CellStyle cellStyle) {
		if (operation == -1) {
			throw new NullPointerException();
		}
		StyleMediator<WorkBookMediator> mediator = null;
		if (operation == 1)
			mediator = new StyleMediator<WorkBookMediator>(this, this.abstractExcelWriter.workbook(), this.getRow());
		else
			mediator = new StyleMediator<WorkBookMediator>(this, this.abstractExcelWriter.workbook(), this.getCell());
		mediator.style(cellStyle);
		return mediator;
	}

	@Override
	public WorkBookMediator height(short height) {
		this.getRow().setHeight(height);
		return this;
	}

	@Override
	public WorkBookMediator heightInPoints(float heightInPoints) {
		this.getRow().setHeightInPoints(heightInPoints);
		return this;
	}

	@Override
	public WorkBookMediator newSheet(String name) {
		if (name == null || "".equals(name)) {
			throw new IllegalArgumentException("数据不能为空");
		}
		this.abstractExcelWriter.setClass(this.abstractExcelWriter.clazz);// 重新初始化容器
		this.cellList.clear();
		this.rowList.clear();
		this.operation = -1;
		this.craList.clear();
		this.abstractExcelWriter.createSheet(name);
		return this;
	}

	@Override
	public WorkBookMediator topBorderColor(int color) {
		if (this.operation == 0) {
			RegionUtil.setTopBorderColor(color, this.craList.get(this.craList.size() - 1),
					this.abstractExcelWriter.sheet, this.abstractExcelWriter.workbook());
		}
		return this;
	}

	@Override
	public WorkBookMediator borderTop(int border) {
		if (this.operation == 0) {
			RegionUtil.setTopBorderColor(border, this.craList.get(this.craList.size() - 1),
					this.abstractExcelWriter.sheet, this.abstractExcelWriter.workbook());
		}
		return this;
	}

	@Override
	public WorkBookMediator bottomBorderColor(int color) {
		if (this.operation == 0) {
			RegionUtil.setBottomBorderColor(color, this.craList.get(this.craList.size() - 1),
					this.abstractExcelWriter.sheet, this.abstractExcelWriter.workbook());
		}
		return this;
	}

	@Override
	public WorkBookMediator borderBottom(int border) {
		if (this.operation == 0) {
			RegionUtil.setBorderBottom(border, this.craList.get(this.craList.size() - 1),
					this.abstractExcelWriter.sheet, this.abstractExcelWriter.workbook());
		}
		return this;
	}

	@Override
	public WorkBookMediator rightBorderColor(int color) {
		if (this.operation == 0) {
			RegionUtil.setRightBorderColor(color, this.craList.get(this.craList.size() - 1),
					this.abstractExcelWriter.sheet, this.abstractExcelWriter.workbook());
		}
		return this;
	}

	@Override
	public WorkBookMediator borderRight(int border) {
		if (this.operation == 0) {
			RegionUtil.setBorderRight(border, this.craList.get(this.craList.size() - 1), this.abstractExcelWriter.sheet,
					this.abstractExcelWriter.workbook());
		}
		return this;
	}

	@Override
	public WorkBookMediator leftBorderColor(int color) {
		if (this.operation == 0) {
			RegionUtil.setLeftBorderColor(color, this.craList.get(this.craList.size() - 1),
					this.abstractExcelWriter.sheet, this.abstractExcelWriter.workbook());
		}
		return this;
	}

	@Override
	public WorkBookMediator borderLeft(int border) {
		if (this.operation == 0) {
			RegionUtil.setBorderLeft(border, this.craList.get(this.craList.size() - 1), this.abstractExcelWriter.sheet,
					this.abstractExcelWriter.workbook());
		}
		return this;
	}

	@Override
	public WorkBookMediator defaultStyle() {
		RowFactory.synchroStyle(this.getCell().getCellStyle(), this.getCra(), this.abstractExcelWriter.sheet, this.abstractExcelWriter.workbook());
		return this;
	}

	@Override
	public WorkBookMediator style(String id) {
		CellStyle cellStyle = this.abstractExcelWriter.excelStyle.getStyle(id);
		if (this.operation == 0) {//单元格
			this.getCell().setCellStyle(cellStyle);
		}
		if (this.operation == 1) {//行
			this.getRow().setRowStyle(cellStyle);
		}
		return this;
	}
}
